<!--数据库表选择对话框组件-->
<!--created by yuyupeng 2023/11/23-->
<template>
  <div>
    <!--按钮-->
    <a-button :disabled="disabled" @click="openModal">
      <template #icon>
        <icon-storage />
      </template>
      {{ buttonWord }}
    </a-button>

    <!--抽屉：选择表-->
    <a-modal
      :visible="visible"
      :width="width"
      :title="title"
      :mask-closable="maskClosable"
      :ok-loading="okLoading"
      @cancel="closeDrawer"
      @ok="selectDbTable"
    >
      <!--查询-->
      <TableSearch
        ref="searchRef"
        expand
        :data-source="SEARCH_FORM"
        @change="searchTable"
      />

      <template v-if="canSelectColumns">
        <splitpanes class="default-theme">
          <pane min-size="30" size="50">
            <!--表格-->
            <a-table
              v-model:selected-keys="selectedKeys"
              :columns="COLUMNS_TABLE"
              :data="tableList"
              row-key="name"
              :row-selection="rowSelection"
              :loading="tbLoading"
              :pagination="pagination"
              :scroll="{ x: 400, y: 500 }"
              @page-change="onPageChange"
              @page-size-change="onPageSizeChange"
              @row-click="rowClick"
            >
              <!-- 插槽：数据源 -->
              <template #dataSource>
                <a-tag color="blue">{{ currentDataSourceName }}</a-tag>
              </template>
            </a-table>
          </pane>
          <pane min-size="30" size="50">
            <!-- 表格详细字段 -->
            <a-table
              v-model:selected-keys="selectedColumnKeys"
              :columns="tbColumnForDetail"
              :data="tbDataForDetail"
              row-key="name"
              :row-selection="rowSelectionForDetail"
              :loading="tbLoadingForDetail"
              :scroll="{ y: 500 }"
              @row-click="rowClickForDetail"
            >
              <!-- 插槽：字段名 -->
              <template #name="{ record }">
                <a-tag color="pinkpurple">{{ record.name }}</a-tag>
              </template>
            </a-table>
          </pane>
        </splitpanes>
      </template>
      <template v-else>
        <!--表格-->
        <a-table
          v-model:selected-keys="selectedKeys"
          :columns="COLUMNS_TABLE"
          :data="tableList"
          row-key="name"
          :row-selection="rowSelection"
          :loading="tbLoading"
          :pagination="pagination"
          :scroll="{ x: '100%', y: 500 }"
          @page-change="onPageChange"
          @page-size-change="onPageSizeChange"
          @row-click="rowClick"
        >
          <!-- 插槽：数据源 -->
          <template #dataSource>
            <a-tag color="blue">{{ currentDataSourceName }}</a-tag>
          </template>
        </a-table>
      </template>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { ref, computed, reactive, toRefs, watch } from 'vue';
  import { Splitpanes, Pane } from 'splitpanes';
  import 'splitpanes/dist/splitpanes.css';
  import TableSearch from '@/common/components/cac-components/advanced-search/index.vue';
  import { DataSourceRecord } from '@/api/infrastructure/model/dataSourceConfigModel';
  import { queryDataSourceRecord } from '@/api/infrastructure/data-source-config';
  import {
    DbTableReq,
    DbTableRecord,
  } from '@/api/infrastructure/model/codegenModel';
  import { queryDbTableRecord } from '@/api/infrastructure/codegen';
  import {
    Notification,
    TableColumnData,
    TableRowSelection,
  } from '@arco-design/web-vue';
  import { Pagination } from '@/types/global';
  import { getDbTableColumns } from '@/api/infrastructure/business-entity';

  const props = defineProps({
    disabled: { type: Boolean, default: false }, // 控制是否禁用
    width: { type: String, default: '1200px' }, // 对话框宽度
    title: { type: String, default: '数据库表选择' }, // 对话标题
    buttonWord: { type: String, default: '库表映射' }, // 按钮文字
    canSelectColumns: { type: Boolean, default: false }, // 是否可以选字段
    // onlyChosenOneEmployee: { type: Boolean, default: false }, // 是否只选择一个人员，如果true，则出现单选框，如果false，则出现复选框
    maskClosable: { type: Boolean, default: true }, // 控制是否允许点击蒙层关闭弹窗
    defaultDataSourceConfigId: { type: Number, default: 0 }, // 默认数据源id
    // cancelText: { type: String, default: '取消' }, // 按钮文字
    // submitWithClose: { type: Boolean, default: true }, // 用于控制submit回调时，是否进行close操作
    // unmountOnClose: { type: Boolean, default: true }, // 关闭时销毁 Modal 里的子元素
    // okButtonProps: { type: Object, default: () => {} },
    // cancelButtonProps: { type: Object, default: () => {} },
    // defaultCheckedMenuList: { type: Array, default: () => [] }, // 默认选中的菜单节点列表，例如[{name: 'dept', title: '部门管理'}]
  });

  const {
    disabled, // 控制是否禁用
    width, // 对话框宽度
    title, // 对话标题
    buttonWord, // 按钮文字
    maskClosable, // 控制是否允许点击蒙层关闭弹窗
    canSelectColumns, // 是否可以选字段
    defaultDataSourceConfigId, // 默认数据源id
    // cancelText, // 按钮文字
    // submitWithClose, // 用于控制submit回调时，是否进行close操作
    // unmountOnClose, // 关闭时销毁 Modal 里的子元素
    // okButtonProps,
    // cancelButtonProps,
    // defaultCheckedMenuList, // 默认选中的人员工号列表，例如['199439']
  } = toRefs(props); // 根据props创建多个 ref 对象

  const emits = defineEmits(['afterSubmit']);
  const visible = ref<boolean>(false);
  const okLoading = ref<boolean>(false);

  const dataSourceList = ref<DataSourceRecord[]>([]);
  const dataSourceLoading = ref<boolean>(false);
  const listDataSource = async () => {
    dataSourceLoading.value = true;
    try {
      const { data } = await queryDataSourceRecord();
      dataSourceList.value = data;
    } finally {
      dataSourceLoading.value = false;
    }
  };
  const searchRef = ref<any>();
  const SEARCH_FORM = computed(() => {
    const options: { label: string; value: string }[] = [];
    dataSourceList.value.forEach((elem) => {
      options.push({ label: elem.name, value: elem.id });
    });
    return [
      {
        labelText: '数据源',
        fieldName: 'dataSourceConfigId',
        type: 'select',
        initialValue: defaultDataSourceConfigId?.value || 0,
        allowSearch: true,
        options,
      },
      { labelText: '表名称', fieldName: 'name', type: 'text' },
      { labelText: '表描述', fieldName: 'comment', type: 'text' },
    ];
  });
  const currentDataSourceName = computed(() => {
    const currentDataSource = dataSourceList.value.filter(
      (e) => e.id === dataSourceConfigId.value
    );

    return currentDataSource.length > 0 ? currentDataSource[0].name : '';
  });

  const rowSelection = reactive<TableRowSelection>({
    type: 'radio',
  });
  const rowSelectionForDetail = reactive<TableRowSelection>({
    // 数据库列表格勾选配置项
    type: 'checkbox',
    showCheckedAll: true,
    onlyCurrent: false,
  });
  const selectedKeys = ref<string[]>([]);
  const selectedColumnKeys = ref<string[]>([]);
  const tableList = ref<DbTableRecord[]>([]);
  const tbDataForDetail = ref<any[]>([]);
  const dataSourceConfigId = ref<string | number>(0);
  // 分页，默认第1页，每页10条
  const basePagination: Pagination = {
    current: 1,
    pageSize: 10,
    showPageSize: true,
    showTotal: true,
  };
  const pagination = reactive({
    ...basePagination,
  });
  const tbLoading = ref<boolean>(false);
  const tbLoadingForDetail = ref<boolean>(false);
  const searchTable = async (params: DbTableReq = {}) => {
    tbLoading.value = true;
    selectedKeys.value = [];
    dataSourceConfigId.value = params.dataSourceConfigId || 0;
    try {
      const { data } = await queryDbTableRecord(params);
      tableList.value = data;
    } finally {
      tbLoading.value = false;
    }
  };

  const COLUMNS_TABLE: TableColumnData[] = [
    {
      title: '序号',
      align: 'center',
      dataIndex: 'index',
      width: 60,
      render: ({ rowIndex }) => rowIndex + 1,
    },
    {
      title: '数据源',
      width: 120,
      dataIndex: 'dataSource',
      slotName: 'dataSource',
      tooltip: true,
    },
    {
      title: '表名称',
      width: 200,
      dataIndex: 'name',
      tooltip: true,
      ellipsis: true,
    },
    {
      title: '表描述',
      width: 300,
      dataIndex: 'comment',
      tooltip: true,
      ellipsis: true,
    },
  ];
  const tbColumnForDetail: TableColumnData[] = [
    {
      title: '序号',
      align: 'center',
      dataIndex: 'index',
      width: 60,
      render: ({ rowIndex }) => rowIndex + 1,
    },
    {
      title: '字段名',
      width: 150,
      dataIndex: 'name',
      tooltip: true,
      slotName: 'name',
    },
    { title: '字段类型', width: 120, dataIndex: 'columnType', tooltip: true },
    {
      title: '字段描述',
      width: 300,
      dataIndex: 'comment',
      tooltip: true,
      ellipsis: true,
    },
  ];

  const openModal = () => {
    listDataSource();
    // searchTable();
    searchRef.value.handleSubmit();
    visible.value = true;
  };
  const closeDrawer = () => {
    selectedKeys.value = [];
    selectedColumnKeys.value = [];
    tbDataForDetail.value = [];
    visible.value = false;
    searchRef.value.resetSearchForm();
  };
  const selectDbTable = async () => {
    try {
      if (canSelectColumns.value) {
        // 可选字段模式
        okLoading.value = true;
        const data = [] as any[];
        tbDataForDetail.value.forEach((item) => {
          if (
            selectedColumnKeys.value.filter((e) => e === item.name).length > 0
          ) {
            data.push(item);
          }
        });
        const dbTableInfo = {
          dataSourceConfigId: dataSourceConfigId.value,
          dataSourceConfigName: dataSourceList.value.filter(
            (e) => e.id === dataSourceConfigId.value
          )[0].name,
          tableName: selectedKeys.value[0],
          tableColumnsList: data,
        };
        okLoading.value = false;
        emits('afterSubmit', dbTableInfo);
        closeDrawer();
      } else {
        // 不可选字段模式
        okLoading.value = true;
        const { data } = await getDbTableColumns(
          dataSourceConfigId.value,
          selectedKeys.value[0]
        );
        const dbTableInfo = {
          dataSourceConfigId: dataSourceConfigId.value,
          dataSourceConfigName: dataSourceList.value.filter(
            (e) => e.id === dataSourceConfigId.value
          )[0].name,
          tableName: selectedKeys.value[0],
          tableColumnsList: data,
        };
        okLoading.value = false;
        emits('afterSubmit', dbTableInfo);
        closeDrawer();
      }
    } catch (error) {
      okLoading.value = false;
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      Notification.error({
        content: `出现异常！${error}`,
        closable: true,
      });
    }
  };
  /**
   * @method
   * @description 页码发生变化触发
   */
  const onPageChange = (current: number) => {
    pagination.current = current;
  };
  /**
   * @method
   * @description 数据条数发生变化触发
   */
  const onPageSizeChange = (pageSize: number) => {
    pagination.pageSize = pageSize;
  };
  /**
   * @description 点击表格数据行触发
   * @param record
   */
  const rowClick = async (record: any) => {
    selectedKeys.value = [record.name];
  };
  /**
   * @description 点击数据库表列表格数据行触发
   * @param record
   */
  const rowClickForDetail = (record: any) => {
    if (selectedColumnKeys.value.indexOf(record.name) > -1) {
      selectedColumnKeys.value = selectedColumnKeys.value.filter(
        (e) => e !== record.name
      );
    } else {
      selectedColumnKeys.value.push(record.name);
    }
  };
  watch(selectedKeys, async (val) => {
    // selectedKeys变化会触发重新查询表格字段
    if (val.length > 0) {
      selectedColumnKeys.value = [];
      tbLoadingForDetail.value = true;
      const { data } = await getDbTableColumns(
        dataSourceConfigId.value,
        selectedKeys.value[0]
      );
      tbLoadingForDetail.value = false;
      tbDataForDetail.value = data;
    }
  });
  watch(currentDataSourceName, async (val) => {
    // 数据源变化会重置已勾选的字段
    if (val.length > 0) {
      selectedColumnKeys.value = [];
      tbDataForDetail.value = [];
    }
  });
</script>
